package com.xiaoke.aspect;

import com.alibaba.fastjson.JSON;
import com.xiaoke.annotation.Log;
import com.xiaoke.domain.entity.SysLog;
import com.xiaoke.enums.BusinessType;
import com.xiaoke.utils.IPUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;


/**
 * @Author xiaoke
 * @Description 操作日志记录处理
 * @Date 2023/7/23 18:52
 */
@Aspect
@Component
public class LogAspect {

    @Autowired
    HttpServletRequest httpServletRequest;

    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);

    /**
     * 定义切面
     */
    @Pointcut("@annotation(com.xiaoke.annotation.Log)")
    public void pt() {
    }

    /**
     * 环绕切点
     * @param pjp join point for advice
     * @return result
     * @throws Throwable throws IllegalArgumentException
     */
    @Around("pt()")
    public Object log(ProceedingJoinPoint pjp) throws Throwable {
        long beginTime = System.currentTimeMillis();
        // 执行切点方法
        Object result = pjp.proceed();
        // 执行时长
        Long runTime = System.currentTimeMillis() - beginTime;
        // 记录日志
        handleLog(pjp,runTime);
        return result;
    }


    private void handleLog(ProceedingJoinPoint pjp,Long runTime) {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        // 获取注解内容
        Log logAnnotation = method.getAnnotation(Log.class);
        // 获取模块
        String title = logAnnotation.title();
        // 获取业务类型
        BusinessType businessType = logAnnotation.businessType();

        Object[] args = pjp.getArgs();
        // 参数
        String params = JSON.toJSONString(args);
        // 请求方法
        String httpMenthod = httpServletRequest.getMethod();
        // ip
        String ip = IPUtils.getIpAddr(httpServletRequest);
        // 请求url
        StringBuffer requestURL = httpServletRequest.getRequestURL();
        // 封装日志对象
        SysLog sysLog = new SysLog(title, businessType, httpMenthod, requestURL.toString(), ip, params, runTime);

        // 这里就是将日志对象输出了，你可以根据需求，把它存到数据库
        // 我这里就简单地打印出来啦！
        System.out.println(sysLog);
    }
}
